using System;
using System.Collections.Generic;
using System.Text;

using System.Management.Automation;

namespace Microsoft.PowerShell.CmdletManagement
{
    [Cmdlet(VerbsCommon.Get, "PsSpecCmdlet")]
    public class GetPsSpecCmdletCommand : Cmdlet
    {
        [Parameter(Mandatory = false, Position = 1, ValueFromPipelineByPropertyName = true)]
        [ValidateLength(1, 50)]
        public String ProjectName
        {
            get
            {
                return _projectName;
            }
            set
            {
                _projectName = value;
            }
        }
        private string _projectName = "*";


        [Parameter(Mandatory = false)]
        public String ServiceUri
        {
            get
            {
                return _serviceUri;
            }
            set
            {
                _serviceUri = value;
            }
        }
        private string _serviceUri = PsSpecCmdletUtils.Constants.ServiceUri;
        
        [Parameter(Mandatory = false, Position = 0, ValueFromPipelineByPropertyName = true)]
        [ValidateLength(1, 50)]
        public String Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private string _name = "*";


        protected override void ProcessRecord()
        {
            PsSpecCmdletService.PsSpecCmdlet[] cmdlets = null;

            PsSpecCmdletService.CmdletService service =
                new PsSpecCmdletService.CmdletService();
            service.Url = ServiceUri;

            service.UseDefaultCredentials = true;

            string convertedName = PsSpecCmdletUtils.ConvertWildcardToSqlWildcard(Name);
            string convertedProject = PsSpecCmdletUtils.ConvertWildcardToSqlWildcard(ProjectName);
            cmdlets = service.GetCmdlet(convertedName, convertedProject);

            bool resultFound = false;            
            List<PsSpecHelpExample> results = new List<PsSpecHelpExample>();

            results = GetHelpExamples(convertedName, convertedProject, service);
            
            Dictionary<int, List<PsSpecHelpExample>> cmdletHelpMapping = new Dictionary<int, List<PsSpecHelpExample>>();

            foreach (PsSpecHelpExample result in results)
            {
                if (!cmdletHelpMapping.ContainsKey(result.CmdletId))
                {
                    cmdletHelpMapping[result.CmdletId] = new List<PsSpecHelpExample>();
                }
                cmdletHelpMapping[result.CmdletId].Add(result);                
            }


            foreach (PsSpecCmdletService.PsSpecCmdlet cmdlet in cmdlets)
            {
                PsSpecHelpExample[] cmdletHelpexamples = new PsSpecHelpExample[0];
                if (cmdletHelpMapping.ContainsKey(cmdlet.Id))
                {
                    cmdletHelpexamples = cmdletHelpMapping[cmdlet.Id].ToArray();
                }

            
                resultFound = true;
                WriteObject(new PsSpecCmdlet(
                        cmdlet.Id, cmdlet.Snapin, cmdlet.Verb, cmdlet.Noun, cmdlet.ProjectName,
                        cmdlet.TeamMembers, cmdlet.ShortDescription, cmdlet.HelpShortDescription, 
                        cmdlet.LongDescription, cmdlet.HelpLongDescription, cmdlet.Status, cmdlet.HelpStatus,
                        cmdlet.SupportsShouldProcess,
                        cmdlet.Notes, cmdlet.SpecExamples, cmdletHelpexamples, cmdlet.InputObject, 
                        cmdlet.HelpInputObjectDescription, cmdlet.OutputObject,
                        cmdlet.OutputObjectDescription, cmdlet.HelpOutputObjectDescription,
                        cmdlet.DefaultParameterSetName, cmdlet.RelatedTo, cmdlet.Custom1, 
                        cmdlet.Custom2, cmdlet.Custom3, cmdlet.Custom4, cmdlet.HelpAdditionalNotes));
            }

            // Generate an error if no cmdlets found, and no globbing was done
            if ((!resultFound) && 
                String.Equals(Name, convertedName, StringComparison.InvariantCultureIgnoreCase) &&
                String.Equals(ProjectName, convertedProject, StringComparison.InvariantCultureIgnoreCase))
            {
                string message = String.Format(resources.CmdletNotFound, Name);
                WriteError(new ErrorRecord(
                    new Exception(message),
                    "CMDLET_NOT_FOUND",
                    ErrorCategory.ObjectNotFound,
                    Name));
            }
        }

        private List<PsSpecHelpExample> GetHelpExamples(string cmdletName, string projectName, PsSpecCmdletService.CmdletService service)
        {
            PsSpecCmdletService.PsSpecHelpExample[] examples = service.GetPsSpecHelpExample(cmdletName, projectName);
            List<PsSpecHelpExample> outboundExamples = new List<PsSpecHelpExample>();
            
            foreach (PsSpecCmdletService.PsSpecHelpExample example in examples)
            {
                PsSpecHelpExample newExample = new PsSpecHelpExample();
                newExample.Id = example.Id;
                newExample.Command = example.Command;
                newExample.Output = example.Output;
                newExample.Description = example.Description;
                newExample.CmdletId = example.CmdletId;

                outboundExamples.Add(newExample);                
            }
            
            return outboundExamples;
        }

    }
}
